package cn.edu.jxau.util;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LinkedList<T> extends List<T> {

    /**
     * 列表元素个数
     */
    private int size;

    /**
     * 列表头指针
     */
    private Node<T> first;

    public LinkedList() {
        first = new Node<>(); // 有头结点
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {

            private Node<T> cursor = first.next;

            @Override
            public boolean hasNext() {
                return cursor != null;
            }

            @Override
            public T next() {

                if (!hasNext()) {
                    throw new NoSuchElementException("迭代器所处位置无元素");
                }
                T item = cursor.item;
                cursor = cursor.next;
                return item;
            }
        };
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void add(int i, T item) {

        // 参数校验 //
        if (i < 0 || i > size) {
            throw new IllegalArgumentException(String.format("i=%d，无效索引值", i));
        }

        // 插入节点 //
        Node<T> cursor = first;
        int p = 0; // 计数
        while (p < i && cursor != null) {
            p++;
            cursor = cursor.next;
        }
        Node<T> node = new Node<>(item);
        node.next = cursor.next;
        cursor.next = node;
        size++;
    }

    @Override
    public T get(int i) {
        
        if(i<0 || i>=size) {
            throw new IllegalArgumentException(String.format("i=%d，无效索引值", i));
        }
        
        Node<T> cursor = first.next;
        int p = 0;
        while(cursor != null) {
            if(p == i) {
                return cursor.item;
            }
            p++;
            cursor = cursor.next;
        }
        return null;
    }

    @Override
    public void remove(T item) {

        Node<T> cursor = first;
        while (cursor.next != null) {
            if (cursor.next.item == null) {
                if (item == null) {
                    cursor.next = cursor.next.next;
                    size--;
                    return ;
                }
            } else {
                if (cursor.next.item.equals(item)) {
                    cursor.next = cursor.next.next;
                    size--;
                    return ;
                }
            }
            cursor = cursor.next;
        }
    }

    @Override
    public T remove(int i) {

        // 参数校验 //
        if (i < 0 || i >= size) {
            throw new IllegalArgumentException(String.format("i=%d，无效索引值", i));
        }

        // 删除节点 //
        int p = 0;
        Node<T> cursor = first;
        while (p < i && cursor != null) {
            p++;
            cursor = cursor.next;
        }
        T item = cursor.next.item;
        cursor.next = cursor.next.next;
        size--;
        return item;
    }

    @Override
    public int indexOf(T item) {
        
        Node<T> cursor = first.next;
        int i = 0;
        if(item == null) {
            while(cursor != null) {
                if(cursor.item == null) {
                    return i;
                }
                cursor = cursor.next;
                i++;
            }
        } else {
            while(cursor != null) {
                if(cursor.item.equals(item)) {
                    return i;
                }
                cursor = cursor.next;
                i++;
            }
        }
        return -1;
    }

    @Override
    public void set(int i, T item) {
        
        if (i < 0 || i >= size) {
            throw new IllegalArgumentException(String.format("i=%d，无效索引值", i));
        }
        int p = 0;
        Node<T> cursor = first.next;
        while(cursor != null) {
            if(i == p) {
                cursor.item = item;
                return ;
            }
            cursor = cursor.next;
            p++;
        }
    }

    @Override
    public String toString() {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("list size=").append(size).append("\t");
        stringBuilder.append("[");
        if (size == 0) {
            stringBuilder.append("]");
        } else {
            Node<T> cursor = first.next;
            while (cursor != null) {
                stringBuilder.append(cursor.item).append(",");
                cursor = cursor.next;
            }
            stringBuilder.deleteCharAt(stringBuilder.length() - 1).append("]");
        }
        return stringBuilder.toString();
    }

    private class Node<T> {
        private T item;
        private Node<T> next;

        public Node() {

        }

        public Node(T item) {
            this.item = item;
        }
    }
}
